﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DDay.iCal;
using DDay.iCal.Components;
using DataTransferObject;

using Engine.TaskVerification;
using Engine.TaskPrioritizeAlgo;
using Engine.ScheduleAlgo;
using System.Windows.Forms;
using System.Drawing;
using DataService;

namespace Engine
{
    class PragmaticAlgorithm : JskeAlgorithm
    {
        #region Attributes
        const int NONE = 0;
        const int PRIORITY = 1;
        const int DUEDATE = 2;

        ProgressBar _progressBar;
        int objectiveCase;
        JskeDataService dataService;
        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="PragmaticAlgorithm"/> class.
        /// </summary>
        /// <param name="t">The t.</param>
        /// <param name="i">The i.</param>
        /// <param name="f">The f.</param>
        /// <param name="s">The s.</param>
        public PragmaticAlgorithm(TaskList t, iCalendar i, FreeTimeList f, SystemConfiguration s)
        {
            _taskList = t;
            _iCal = i;
            freeTimeList = f;
            systemConfiguration = s;
            _PrioritizeTaskList = new PragmaticPrioritizeTaskListAlgo();
            _VerifyTaskConstraint = new PragmaticVerifyTaskConstraintAlgo();
            _ScheduleTaskList = new PragmaticScheduleAlgorithm();
            PriorityReport = null;
            ScheduReport = null;
            ConstraintViolate = null;
        }

        public PragmaticAlgorithm(TaskList t, iCalendar i, MappedFreeTimeList mf, SystemConfiguration s, JskeDataService dataService)
        {
            _taskList = t;
            _iCal = i;
            mappedFreeTimeList = mf;
            systemConfiguration = s;
            //_PrioritizeTaskList = new PragmaticPrioritizeTaskListAlgo();
            _VerifyTaskConstraint = new PragmaticVerifyTaskConstraintAlgo();
            _ScheduleTaskList = new PragmaticScheduleAlgorithm();
            PriorityReport = null;
            ScheduReport = null;
            ConstraintViolate = null;
            this.dataService = dataService;
        }

        #endregion

        public override void setProgressBar(ProgressBar p)
        {
            _progressBar = p;
        }

        public override void updateProgressBar(ProgressBar progressBar1, int val)
        {
            progressBar1.Refresh();
            progressBar1.Value = val;
            int percent = (int)(((double)progressBar1.Value / (double)progressBar1.Maximum) * 100);
            progressBar1.CreateGraphics().DrawString(percent.ToString() + "%", new Font("Arial", (float)8.25, FontStyle.Bold), Brushes.Blue, new PointF(progressBar1.Width / 2 - 10, progressBar1.Height / 2 - 7));

        }

        #region Methods Override

        /// <summary>
        /// Verifies the task constraint.
        /// </summary>
        /// <returns></returns>
        protected override ConstraintViolation verifyTaskConstraint()
        {
            ConstraintViolate = new ConstraintViolation();
            ConstraintViolation c = ConstraintViolate;
            _VerifyTaskConstraint.doTaskVerification(_taskList, mappedFreeTimeList, systemConfiguration, ref c);
            return c;
        }

        /// <summary>
        /// Sets the priority task list.
        /// </summary>
        /// <returns></returns>
        protected override PrioritizeReport setPriorityTaskList()
        {
            //lấy criteria từ xml hoặc SystemConfiguration
            PriorityCriteria criteria = new PriorityCriteria();

            PriorityReport = new PrioritizeReport();
            PrioritizeReport p = PriorityReport;
            //_PrioritizeTaskList.setPriorityParameter(ref _taskList, systemConfiguration, criteria, ref p);
            _PrioritizeTaskList.JSKECalculatePriority();
            return p;
        }

        public override List<Event> run()
        {
            //const int DYNAMIC_SCHEDULE = 1;
            //const int PRIORITY_ONLY_SCHEDULE = 2;
            //const int DUEDATE_ONLY_SCHEDULE = 3;
            //const int PRIORITY_THEN_DUEDATE_SCHEDULE = 4;
            //const int DUEDATE_THEN_PRIORITY_SCHEDULE = 5;

            int[,] objectiveRequirement = new int[3,3] { {1,1,1},
                                                         {2,2,4},
                                                         {3,5,3}};
            objectiveCase = objectiveRequirement[systemConfiguration.TabTaskData.OrderBy, systemConfiguration.TabTaskData.AndThenBy];
            //hàng là orderby, cột là andthenby
            
            verifyTaskConstraint();
            //setPriorityTaskList();
            updateProgressBar(_progressBar, 63);
            return scheduleTaskList();
        }

        /// <summary>
        /// Schedules the task list.
        /// </summary>
        /// <returns></returns>
        protected override List<Event> scheduleTaskList()
        {
            ScheduReport = new ScheduleReport();
            ScheduleReport s = ScheduReport;
            return _ScheduleTaskList.doScheduleTaskList(_taskList, mappedFreeTimeList, systemConfiguration, _iCal, ref s, objectiveCase, dataService);
        }

        #endregion
    }
}
